package graphics;
/*
 * Zombinoes: Peter Mosher, Michael Pitts
 * TCSS 491 - Computational Worlds
 * Project 1
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.media.opengl.GL2;

/**
 * This is an internal node in a graphics tree, it can be rotated, translated 
 * and scaled before rendering it's children.
 * @author Michael Pitts
 * @version Jan 23, 2012
 */
public class InternalNode extends AbstractNode {
	
	public static final int REMOVE_NEXT = 1;
	
	/** The list of child nodes for this Internal Node.*/
	private final List<Node> my_nodes = new ArrayList<Node>();
	
	/** If true, the next select test should remove what is selected. */
	private boolean my_remove_next;
	
	/**
	 * Creates a new Internal Node with the given nodes as children.
	 */
	public InternalNode(final Collection<Node> the_nodes) {
		super();
		my_nodes.addAll(the_nodes);
		my_remove_next = false;
	}

	@Override public List<Node> getChildren() {
		return Collections.unmodifiableList(my_nodes);
	}
	
	@Override protected void render(final GL2 the_gl) {
		for (Node node : my_nodes) {
			node.display(the_gl);
		}
	}

	@Override protected boolean renderTest(final GL2 the_gl) {
		boolean any_selects = false;
		Node node;
		for (int i = my_nodes.size() - 1; i > -1; i--) {
			node = my_nodes.get(i);
			any_selects |= node.testSelect(the_gl);
			if (my_remove_next && any_selects) {
				my_nodes.remove(i);
				my_remove_next = false;
				any_selects = false;
			}
		}
		return any_selects;
	}
	
	@Override public void update(final Object... the_data) {
		if (the_data.length == 1 && Integer.class.isInstance(the_data[0]) && 
				((Integer) the_data[0]).intValue() == REMOVE_NEXT) {
			my_remove_next = true;
		} else {
			for (Node child : my_nodes) {
				child.update(the_data);
			}
		}
	}
	
	/**
	 * Adds the given node to this node's children.
	 * @param the_node is the node to add.
	 */
	public void addChild(final Node the_node) {
		my_nodes.add(the_node);
	}
	
	/**
	 * Removes the given node from this node's children.
	 * @param the_node the node to remove.
	 */
	public void removeChild(final Node the_node) {
		my_nodes.remove(the_node);
	}
}
